<?php
# Arlicle 图像处理类

/*
使用例子:
$image = new Image();
$image->open('xxx.jpg');
$image->thumbnail(array('width'=>48, 'height'=>48), quality=100);
$image->save('sss.jpg');
*/

class Image {

    /* 可以处理的格式 */
    var $mimes = array('image/gif', 'image/jpeg', 'image/png');

    # 可以输出的格式
    var $output_mimes = array('.gif', '.jpg', '.png');

    var $action = true;
    # 错误信息
    var $errors = array();
    function __construct() {
        # 判断是否安装符合要求的GD库
        if (!extension_loaded('gd')) {
            $this->action = false;
        }
    }

    /*
        打开图像,创建图像对象
    */
    function open($image_path) {

        if (!is_readable($image_path)) {
            return $this->errors[] = '图片不可阅读';
        }

        $this->image_path = $image_path;
        $this->image_info = @getimagesize($image_path);
        # 读取出错|文件出错|读取空
        if (!$this->image_info) {
            return $this->errors[] = '图片读取出错';
        }

        # 看图片是否类型符合
        if (!in_array($this->image_info['mime'], $this->mimes)) {
            return $this->errors[] = '不支持该图片类型';
        }

        # 获取图像资源
        $this->image_handle = $this->get_img_resource();

        if (!$this->image_handle) {
            return $this->errors[] = '图片读取出错';
        }
    }


    /*
        设置缩略图信息
        array('width'=>1, 'height'=> 1)
        quality = 100
        force 是用来强制转换图片大小
    */
    
    function thumbnail($size = array(), $force = false) {
        if (!empty($this->errors)) {
            return false;
        }
        $size = array_merge(array('width'=> 0, 'height'=> 0), $size);
        $scale = $this->image_info[0]/$this->image_info[1];

        #如果为强制, 大图会被强制为小图, 小图会被强制为大图
        if ($force) {
            $this->thumbnail['width'] = $size['width'];
            $this->thumbnail['height'] = $size['height'];
        # 如果原图比缩略图小,则取原图大小
        } else if ($this->image_info[0] < $size['width'] && $this->image_info[1] < $size['height']) {
            $this->thumbnail['width'] = $this->image_info[0];
            $this->thumbnail['height'] = $this->image_info[1];
        } else if ($size['width'] == 0) {
            $this->thumbnail['width'] = $size['height'] * $scale;
            $this->thumbnail['height'] = $size['height'];
        } else if ($size['height'] == 0) {
            $this->thumbnail['width'] = $size['width'];
            $this->thumbnail['height'] = $size['width'] / $scale;
        } else {
            #为了等比缩略, 那一边缩略的更小就用哪一边进行缩略
            if ($this->image_info[0] / $size['width'] > $this->image_info[1] / $size['height']) {
                $this->thumbnail['width'] = $size['width'];
                $this->thumbnail['height'] = $size['width'] / $scale;
            } else {
                $this->thumbnail['width'] = $size['height'] * $scale;
                $this->thumbnail['height'] = $size['height'];
            }
        }

        $this->thumbnail['action'] = true;
    }


    function save($image_path, $info = array()) {
        if (!empty($this->errors)) {
            return false;
        }
        $ini_info = array(
            'quality'=>100,
            'bgcolor'=>'#ffffff',
        );
        $info = array_merge($ini_info, $info);

        $path = dirname($image_path);
        if (!is_writable($path)) {
            return false;
        }

        $pos = strrpos($image_path, '.');
        if ($pos) {
            $this->output_type = strtolower(substr($image_path, $pos));
            if (!in_array($this->output_type, $this->output_mimes)) {
                return false;
            }
        } else {
            return false;
        }

        if (!empty($this->thumbnail['action'])) {
            $this->thumbnail_save($image_path, $info);
        }
        
        
    }

    /*
        不同类型的图的判断和保存设置
    */
    function thumbnail_save($thumbnail_path, $info=array()) {
        $thumbnail  = imagecreatetruecolor($this->thumbnail['width'], $this->thumbnail['height']);
        $bgcolor = trim($info['bgcolor'],"#");
        sscanf($bgcolor, "%2x%2x%2x", $red, $green, $blue);

        $clr = imagecolorallocate($thumbnail, $red, $green, $blue);
        imagefilledrectangle($thumbnail, 0, 0, $this->thumbnail['width'], $this->thumbnail['height'], $clr);
        imagecopyresampled($thumbnail, $this->image_handle, 0, 0, 0, 0, $this->thumbnail['width'], $this->thumbnail['height'], $this->image_info[0], $this->image_info[1]);
        
        switch($this->output_type) {
            case '.jpg':
                imagejpeg($thumbnail, $thumbnail_path);
                break;
            case '.png':
                imagepng($thumbnail, $thumbnail_path);
                break;
            case '.gif':
                imagegif($thumbnail, $thumbnail_path);
                break;
        }
        imagedestroy($thumbnail);

    }

    /*
        根据不同类型的图片,获取图像handle
    */

    function get_img_resource() {
        switch ($this->image_info['mime']) {
            case 'image/gif':
                $resource = imagecreatefromgif($this->image_path);
                break;

            case 'image/jpeg':
                $resource = imagecreatefromjpeg($this->image_path);
                break;

            case 'image/png':
                $resource = imagecreatefrompng($this->image_path);
                break;

            default:
                return false;
        }
        return $resource;
    }

    function watermark($watermark_path, $position = 5, $transparent = 50) {
        if (!is_readable($watermark_path)) {
            return false;
        }
        $watermark_info     = @getimagesize($watermark_path);
        $watermark_handle   = imagecreatefromgif($watermark_path);

        if (!$watermark_handle) {
            return false;
        }

        switch ($position) {
            case '1':
                $x = 0;
                $y = 0;
                break;
            case '2':
                $x = $this->image_info[0]/2 - $watermark_info[0]/2;
                $y = 0;
                break;
            case '3':
                $x = $this->image_info[0] - $watermark_info[0];
                $y = 0;
                break;
            case '4':
                $x = 0;
                $y = $this->image_info[1]/2 - $watermark_info[1]/2;
                break;
            case '5':
                $x = $this->image_info[0]/2 - $watermark_info[0]/2;
                $y = $this->image_info[1]/2 - $watermark_info[1]/2;
                break;
            case '6':
                $x = $this->image_info[0] - $watermark_info[0];
                $y = $this->image_info[1]/2 - $watermark_info[1]/2;
                break;
            case '7':
                $x = 0;
                $y = $this->image_info[1] - $watermark_info[1];
                break;
            case '8':
                $x = $this->image_info[0]/2 - $watermark_info[0]/2;
                $y = $this->image_info[1] - $watermark_info[1];
                break;
            case '9':
                $x = $this->image_info[0] - $watermark_info[0];
                $y = $this->image_info[1] - $watermark_info[1];
                break;
            default:
                $x = $this->image_info[0]/2 - $watermark_info[0]/2;
                $y = $this->image_info[1]/2 - $watermark_info[1]/2;
        }
        imagecopymerge($this->image_handle, $watermark_handle, $x, $y, 0, 0,$watermark_info[0], $watermark_info[1], $transparent);
        switch ($this->image_info[2] ) {
            case 'image/gif':
            case 1:
                imagegif($this->image_handle,  $this->image_path);
                break;

            case 'image/pjpeg':
            case 'image/jpeg':
            case 2:
                imagejpeg($this->image_handle, $this->image_path);
                break;

            case 'image/x-png':
            case 'image/png':
            case 3:
                imagepng($this->image_handle,  $this->image_path);
                break;

            default:
                return false;
        }

        imagedestroy($this->image_handle);

        $path = realpath($this->image_path);
        if ($path) {
            return true;
        } else {
            return false;
        }
    }

}

?>
